package api

import (
	"fmt"
	"gin-init/internal/types"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator"
	"github.com/google/wire"
)

var ApiSet = wire.NewSet(NewDemoApi, wire.Struct(new(Api), "*"))

type Api struct {
	DemoApi
}

func NewDemoApi() (api *DemoApi, err error) {
	return &DemoApi{}, nil
}

func ResponseSuccessEmpty(ctx *gin.Context) {
	ctx.JSON(http.StatusOK, struct{}{})
}

func ApiSuccessJsonResponse(ctx *gin.Context, v interface{}) {
	ctx.JSON(http.StatusOK, v)
}

func ApiErrorJsonResponse(ctx *gin.Context, err error) {
	var (
		resp = types.ErrorRespone{
			ErrCode: 20000,
			ErrMsg:  "system exception",
			ErrTips: "系统异常",
		}
		httpCode = http.StatusInternalServerError
	)
	switch eType := err.(type) {
	//业务异常
	case types.BusinessError:
		if eType.GetHttpCode() != 0 {
			httpCode = eType.GetHttpCode()
		}
		resp = eType.ErrorRespone
		//参数异常
	case validator.ValidationErrors:
		httpCode = http.StatusBadRequest
		resp.ErrCode = 10000
		resp.ErrMsg = "invalid parameter"
		errTips := make([]string, 0)
		for _, err := range eType {
			switch err.Tag() {
			case "required":
				errTips = append(errTips, fmt.Sprintf("%s is required", err.Field()))
			case "max":
				errTips = append(errTips, fmt.Sprintf("%s cannot be longer than %s", err.Field(), err.Param()))
			case "min":
				errTips = append(errTips, fmt.Sprintf("%s must be longer than %s", err.Field(), err.Param()))
			case "email":
				errTips = append(errTips, "Invalid email format")
			case "phone":
				errTips = append(errTips, "Invalid phone format")
			case "len":
				errTips = append(errTips, fmt.Sprintf("%s must be %s characters long", err.Field(), err.Param()))
			case "oneof":
				errTips = append(errTips, fmt.Sprintf("%s must be one of [%s]", err.Field(), err.Param()))
			case "lte", "gte", "lt", "gt":
				errTips = append(errTips, fmt.Sprintf("%s must be %s %s", err.Field(), err.Tag(), err.Param()))
			case "numeric":
				errTips = append(errTips, fmt.Sprintf("%s must be %s %s", err.Field(), err.Tag(), err.Param()))
			default:
				errTips = append(errTips, fmt.Sprintf("%s must be %s %s", err.Field(), err.Tag(), err.Param()))
			}
		}
		resp.ErrTips = strings.Join(errTips, ",")
	default:
		resp.ErrMsg = err.Error()
	}
	ctx.AbortWithStatusJSON(httpCode, resp)
}
